#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>

#define FIFO_NAME "04_test.fifo"
#define STR_TEST "Hello FIFO"

int main(int argc, char const *argv[])
{
    int iRet = 0;
    iRet = mkfifo( FIFO_NAME, 0664 );
    if ( iRet == -1 && errno == EEXIST )
    {
        perror( "fail mkfifo" );
        return -1;
    }

    pid_t pid = fork();
    if ( pid > 0)
    {
        int fdWrite;

        fdWrite = open( FIFO_NAME, O_WRONLY );
        write( fdWrite, STR_TEST, sizeof(STR_TEST) );
        close( fdWrite );
    }
    else if ( pid == 0)
    {
        int fdRead;
        char strReadBuff[100] = {0};

        sleep( 5 );

        fdRead = open( FIFO_NAME, O_RDONLY );
        read( fdRead, strReadBuff, sizeof(strReadBuff) );
        close( fdRead );

        printf( "strReadBuff: %s\n", strReadBuff );
        
    }
    else
    {
        perror( "fail fork" );
        return -1;
    }

    sleep( 5 ); 

    remove( FIFO_NAME );

    return 0;
}


/*

所涉及函数
    mkfifo
    open
    write
    read
    close
    remove

流程
    创建fifo文件

    创建一个子进程

    父进程写入fifo
        打开fifo (写模式)
        写入fifo
        关闭fifo

    子进程读取fifo
        打开fifo (读模式)
        读取fifo
        关闭fifo

    删除fifo文件

注意点
    1) 创建fifo文件时, mode参数可以参考 mkfifo 命令或者 touch 命令, 0664 即可
    2) 重复运行 a.out 时, 如果fifo文件已经存在, 会报错, 可以忽略这个错误. 
    3) 每个进程有独立的 file descriptor, 所以在创建子进程之后, 分别打开fifo文件
    4) fifo文件必须建立至少一个读和一个写, 如果没有建立, 则会阻塞等待.
    5) remove会阻塞执行直到fifo中所有数据被读取
    
*/